# -*- coding: utf-8 -*-
"""
Pandas merge 函数示例
merge 用于根据一个或多个键将 DataFrame 进行数据库风格的连接
"""

import pandas as pd
import numpy as np

# ============= 示例1: 内连接（Inner Join） =============
print("=" * 50)
print("示例1: 内连接（Inner Join）")
print("=" * 50)

# 创建两个 DataFrame
df_employees = pd.DataFrame({
    '员工ID': [1, 2, 3, 4],
    '姓名': ['张三', '李四', '王五', '赵六'],
    '部门ID': [101, 102, 103, 101]
})

df_departments = pd.DataFrame({
    '部门ID': [101, 102, 104],
    '部门名称': ['技术部', '市场部', '人事部']
})

print("\n员工信息表:")
print(df_employees)
print("\n部门信息表:")
print(df_departments)

# 内连接：只保留两个表中都存在的键
result1 = pd.merge(df_employees, df_departments, on='部门ID', how='inner')
print("\n内连接结果（只保留匹配的记录）:")
print(result1)

# ============= 示例2: 左连接（Left Join） =============
print("\n" + "=" * 50)
print("示例2: 左连接（Left Join）")
print("=" * 50)

# 左连接：保留左表的所有记录
result2 = pd.merge(df_employees, df_departments, on='部门ID', how='left')
print("\n左连接结果（保留所有员工，没有匹配的部门显示 NaN）:")
print(result2)

# ============= 示例3: 右连接（Right Join） =============
print("\n" + "=" * 50)
print("示例3: 右连接（Right Join）")
print("=" * 50)

# 右连接：保留右表的所有记录
result3 = pd.merge(df_employees, df_departments, on='部门ID', how='right')
print("\n右连接结果（保留所有部门，没有员工的部门显示 NaN）:")
print(result3)

# ============= 示例4: 外连接（Outer Join） =============
print("\n" + "=" * 50)
print("示例4: 外连接（Outer Join）")
print("=" * 50)

# 外连接：保留两个表的所有记录
result4 = pd.merge(df_employees, df_departments, on='部门ID', how='outer')
print("\n外连接结果（保留所有记录，缺失值显示 NaN）:")
print(result4)

# ============= 示例5: 基于多个键合并 =============
print("\n" + "=" * 50)
print("示例5: 基于多个键合并")
print("=" * 50)

# 创建包含多个键的 DataFrame
df_sales = pd.DataFrame({
    '年份': [2023, 2023, 2024, 2024],
    '季度': [1, 2, 1, 2],
    '销售额': [100, 150, 120, 180]
})

df_targets = pd.DataFrame({
    '年份': [2023, 2023, 2024, 2024],
    '季度': [1, 2, 1, 2],
    '目标': [90, 140, 110, 170]
})

print("\n销售数据:")
print(df_sales)
print("\n目标数据:")
print(df_targets)

# 基于多个键合并
result5 = pd.merge(df_sales, df_targets, on=['年份', '季度'])
print("\n基于年份和季度合并结果:")
print(result5)

# ============= 示例6: 列名不同时的合并 =============
print("\n" + "=" * 50)
print("示例6: 列名不同时的合并（使用 left_on 和 right_on）")
print("=" * 50)

# 创建列名不同的 DataFrame
df_orders = pd.DataFrame({
    '订单ID': [1001, 1002, 1003],
    '客户编号': [201, 202, 203],
    '金额': [500, 800, 600]
})

df_customers = pd.DataFrame({
    '客户ID': [201, 202, 204],
    '客户姓名': ['公司A', '公司B', '公司C']
})

print("\n订单表:")
print(df_orders)
print("\n客户表:")
print(df_customers)

# 使用 left_on 和 right_on 指定不同的列名
result6 = pd.merge(df_orders, df_customers, left_on='客户编号', right_on='客户ID', how='left')
print("\n合并结果（列名不同）:")
print(result6)

# 删除重复的列
result6_clean = result6.drop('客户ID', axis=1)
print("\n删除重复列后:")
print(result6_clean)

# ============= 示例7: 处理重复列名（使用 suffixes） =============
print("\n" + "=" * 50)
print("示例7: 处理重复列名（使用 suffixes）")
print("=" * 50)

# 创建有重复列名的 DataFrame
df_product1 = pd.DataFrame({
    '产品ID': [1, 2, 3],
    '价格': [100, 200, 150],
    '库存': [50, 30, 40]
})

df_product2 = pd.DataFrame({
    '产品ID': [1, 2, 3],
    '价格': [95, 210, 145],
    '供应商': ['供应商A', '供应商B', '供应商C']
})

print("\n产品表1（本地库存）:")
print(df_product1)
print("\n产品表2（供应商报价）:")
print(df_product2)

# 使用 suffixes 区分重复的列名
result7 = pd.merge(df_product1, df_product2, on='产品ID', suffixes=('_本地', '_供应商'))
print("\n合并结果（使用 suffixes 区分重复列）:")
print(result7)

# ============= 示例8: 基于索引合并 =============
print("\n" + "=" * 50)
print("示例8: 基于索引合并")
print("=" * 50)

# 创建带索引的 DataFrame
df_scores1 = pd.DataFrame({
    '数学': [85, 90, 78]
}, index=['学生A', '学生B', '学生C'])

df_scores2 = pd.DataFrame({
    '英语': [88, 92, 80]
}, index=['学生A', '学生B', '学生C'])

print("\n数学成绩:")
print(df_scores1)
print("\n英语成绩:")
print(df_scores2)

# 基于索引合并
result8 = pd.merge(df_scores1, df_scores2, left_index=True, right_index=True)
print("\n基于索引合并结果:")
print(result8)

# ============= 示例9: 一对多关系的合并 =============
print("\n" + "=" * 50)
print("示例9: 一对多关系的合并")
print("=" * 50)

# 一个部门有多个员工
df_dept_info = pd.DataFrame({
    '部门ID': [101, 102],
    '部门名称': ['技术部', '市场部'],
    '部门经理': ['经理A', '经理B']
})

df_emp_detail = pd.DataFrame({
    '员工姓名': ['张三', '李四', '王五', '赵六'],
    '部门ID': [101, 101, 102, 102],
    '工资': [8000, 9000, 7000, 7500]
})

print("\n部门信息:")
print(df_dept_info)
print("\n员工详情:")
print(df_emp_detail)

# 一对多合并
result9 = pd.merge(df_emp_detail, df_dept_info, on='部门ID')
print("\n一对多合并结果:")
print(result9)

# ============= 示例10: 使用 indicator 参数追踪合并来源 =============
print("\n" + "=" * 50)
print("示例10: 使用 indicator 参数追踪合并来源")
print("=" * 50)

df_a = pd.DataFrame({
    'ID': [1, 2, 3],
    '值A': ['a1', 'a2', 'a3']
})

df_b = pd.DataFrame({
    'ID': [2, 3, 4],
    '值B': ['b2', 'b3', 'b4']
})

print("\nDataFrame A:")
print(df_a)
print("\nDataFrame B:")
print(df_b)

# 使用 indicator 参数
result10 = pd.merge(df_a, df_b, on='ID', how='outer', indicator=True)
print("\n使用 indicator 追踪数据来源:")
print(result10)

# 自定义 indicator 列名
result10_custom = pd.merge(df_a, df_b, on='ID', how='outer', indicator='来源')
print("\n自定义 indicator 列名:")
print(result10_custom)

print("\n" + "=" * 50)
print("所有示例执行完成！")
print("=" * 50)

